package com.ccp.dev.form.model;

import com.ccp.dev.core.basic.model.BaseModel;
import com.ccp.dev.core.util.BeanUtils;
import com.ccp.dev.core.util.StringPool;
import com.ccp.dev.core.util.StringUtil;
import com.ccp.dev.form.util.FieldPool;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * bpm_form_field Model对象
 *
 * @author zhaowj
 */
@XmlRootElement(name = "field")
@XmlAccessorType(XmlAccessType.NONE)
public class FormField extends BaseModel<FormField> {

    public static final String DATATYPE_VARCHAR = "varchar";
    public static final String DATATYPE_CLOB = "clob";
    public static final String DATATYPE_DATE = "date";
    public static final String DATATYPE_NUMBER = "number";

    public static final short VALUE_FROM_IDENTITY = 3;

    /**
     * 标记删除：是
     */
    public final static int IS_DELETE_Y = 1;
    /**
     * 标记删除：否
     */
    public final static int IS_DELETE_N = 0;

    /**
     * 字段id
     */
    @XmlAttribute
    protected String fieldId;

    /**
     * 表id
     */
    @XmlAttribute
    protected String tableId;

    /**
     * 字段名称
     */
    @XmlAttribute
    protected String fieldName;

    /**
     * 字段类型
     */
    @XmlAttribute
    protected String fieldType;

    /**
     * 是否必填
     */
    @XmlAttribute
    protected Short isRequired = 0;

    /**
     * 是否列表显示
     */
    @XmlAttribute
    protected Short isList = 1;

    /**
     * 是否查询显示
     */
    @XmlAttribute
    protected Short isQuery = 1;

    /**
     * 说明
     */
    @XmlAttribute
    protected String fieldDesc;

    /**
     * 字符长度，仅针对字符类型
     */
    @XmlAttribute
    protected Integer charLen = 0;

    /**
     * 整数长度，仅针对数字类型
     */
    @XmlAttribute
    protected Integer intLen = 0;

    /**
     * 小数长度，仅针对数字类型
     */
    @XmlAttribute
    protected Integer decimalLen = 0;

    /**
     * 小数据字典的类别，仅针对数据字典类型
     */
    @XmlAttribute
    protected String dictType;

    /**
     * 是否删除
     */
    @XmlAttribute
    protected Short isDeleted = 0;

    /**
     * 验证规则
     */
    @XmlAttribute
    protected String validRule;

    /**
     * 字段原名
     */
    @XmlAttribute
    protected String originalName;

    /**
     * 排列顺序
     */
    @XmlAttribute
    protected Integer sn = 0;

    /**
     * 值来源 0-表单 1-脚本
     */
    @XmlAttribute
    protected Short valueFrom = 0;

    /**
     * 脚本
     */
    @XmlAttribute
    protected String script;

    /**
     * 控件类型
     */
    @XmlAttribute
    protected Short controlType = 0;

    /**
     * 是否隐藏域
     */
    @XmlAttribute
    protected Short isHidden = 0;

    /**
     * 是否流程变量
     */
    @XmlAttribute
    protected Short isFlowVar = 0;

    /**
     * 流水号别名
     */
    @XmlAttribute
    protected String identity;

    /**
     * 下拉框
     */
    @XmlAttribute
    protected String options;

    /**
     * 控件属性
     */
    @XmlAttribute
    protected String ctlProperty = "";

    /**
     * 新添加的列
     */
    @XmlAttribute
    protected boolean isAdded = false;

    /**
     * 支持手机客户端显示
     */
    @XmlAttribute
    protected Short isAllowMobile = 0;

    /**
     * 文字为日期格式
     */
    @XmlAttribute
    protected Short isDateString = 0;

    /**
     * 文字取当前日期
     */
    @XmlAttribute
    protected Short isCurrentDateStr = 0;

    /**
     * 控件样式
     */
    @XmlAttribute
    protected String style;

    /**
     * 流程引用
     */
    @XmlAttribute
    protected Short isReference;

    /**
     * 非数据库字段 日期格式
     */
    @XmlAttribute
    protected String datefmt;

    /**
     * 复选按钮默认值
     */
    protected String checkboxDefault;

    /**
     * 单选按钮默认值
     */
    protected String radioDefault;

    /**
     * 选择器ID脚本。
     */
    @XmlAttribute
    protected String scriptID = "";

    /**
     * 该字段是否主键 1为主键
     */
    @XmlAttribute
    protected short type;

    /**
     * web印章验证 1为支持，0为不用
     */
    @XmlAttribute
    protected Short isWebSign = 0;

    /**
     * 数字类型是否显示千分位
     */
    @XmlAttribute
    protected Short isShowComdify;

    /**
     * 数字类型显示货币符号
     */
    @XmlAttribute
    protected String coinValue;

    /**
     * 控制文件后缀
     */
    @XmlAttribute
    protected String fileTypes;

    /**
     * 字段加密
     */
    public final static Integer ISENCRYPT = 1;

    /**
     * 字段不加密
     */
    public final static Integer ISENCRYPT_NOT = 0;

    /**
     * 是否加密
     */
    @XmlAttribute
    protected Integer isEncrypt = ISENCRYPT_NOT;

    /**
     * 加密类名.方法名
     */
    @XmlAttribute
    protected String encryptClass;

    /**
     * 解密类名.方法名
     */
    @XmlAttribute
    protected String decryptClass;

    /**
     * 数据字典名称
     */
    @XmlAttribute
    protected String dictName;

    /**
     * 列表显示 0不显示 1显示
     */
    protected int listShow;

    /**
     * 弹框显示 0不显示 1显示
     */
    protected int dialogShow;

    public static int LIST_SHOW_TRUE = 1;
    public static int LIST_SHOW_FALSE = 0;
    public static int DIALOG_SHOW_TRUE = 1;
    public static int DIALOG_SHOW_FALSE = 0;
    public static short VALUE_FROM_FORM = 0;
    public static short VALUE_FROM_SCRIPT_SHOW = 1;
    public static short VALUE_FROM_SCRIPT_HIDDEN = 2;

    /**
     * 人员选择器单选
     */
    public static String CONTROL_TYPE_USER_SINGLE = "4";
    /**
     * 人员选择器多选
     */
    public static String CONTROL_TYPE_USER_MULTIPLE = "8";
    /**
     * 角色选择器单选
     */
    public static String CONTROL_TYPE_ROLE_SINGLE = "17";
    /**
     * 角色选择器多选
     */
    public static String CONTROL_TYPE_ROLE_MULTIPLE = "5";
    /**
     * 组织选择器单选
     */
    public static String CONTROL_TYPE_ORG_SINGLE = "18";
    /**
     * 组织选择器多选
     */
    public static String CONTROL_TYPE_ORG_MULTIPLE = "6";



    /**
     * 是否：是
     */
    public final static short IS_Y = 1;

    /**
     * 是否：否
     */
    public final static short IS_N = 0;

    /**
     * 隐藏
     */
    public static final short HIDDEN = 1;

    /**
     * 非隐藏
     */
    public static final short NO_HIDDEN = 0;

    /**
     * 隐藏字段+ID
     */
    public static final String FIELD_HIDDEN = "ID";


    /**
     * 是否包含隐藏或者删除字段 0为正常字段
     */
    public static final int FIELD_NORMAL = 0;


    /**
     * 是否包含隐藏或者删除字段  1为正常字段加上隐藏字段
     */
    public static final int FIELD_NORMAL_HIDDEN = 1;


    /**
     * 是否包含隐藏或者删除字段  2 为正常字段加上逻辑删除字段
     */
    public static final int FIELD_NORMAL_LOGICDEL = 2;

    //
    /**
     * 非数据库字段
     */
    private String defValue;

    public String getDefValue() {
        return defValue;
    }

    public void setDefValue(String defValue) {
        this.defValue = defValue;
    }

    public String getFieldId() {
        return fieldId;
    }

    public void setFieldId(String fieldId) {
        this.fieldId = fieldId;
    }

    public String getTableId() {
        return tableId;
    }

    public void setTableId(String tableId) {
        this.tableId = tableId;
    }

    public String getFieldName() {
        return fieldName;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public String getFieldType() {
        return fieldType;
    }

    public void setFieldType(String fieldType) {
        this.fieldType = fieldType;
    }

    public Short getIsRequired() {
        return isRequired;
    }

    public void setIsRequired(Short isRequired) {
        this.isRequired = isRequired;
    }

    public Short getIsList() {
        return isList;
    }

    public void setIsList(Short isList) {
        this.isList = isList;
    }

    public Short getIsQuery() {
        return isQuery;
    }

    public void setIsQuery(Short isQuery) {
        this.isQuery = isQuery;
    }

    public String getFieldDesc() {
        return fieldDesc;
    }

    public void setFieldDesc(String fieldDesc) {
        this.fieldDesc = fieldDesc;
    }

    public Integer getCharLen() {
        return charLen;
    }

    public void setCharLen(Integer charLen) {
        this.charLen = charLen;
    }

    public Integer getIntLen() {
        return intLen;
    }

    public void setIntLen(Integer intLen) {
        this.intLen = intLen;
    }

    public Integer getDecimalLen() {
        return decimalLen;
    }

    public void setDecimalLen(Integer decimalLen) {
        this.decimalLen = decimalLen;
    }

    public String getDictType() {
        return dictType;
    }

    public void setDictType(String dictType) {
        this.dictType = dictType;
    }

    public Short getIsDeleted() {
        return isDeleted;
    }

    public void setIsDeleted(Short isDeleted) {
        this.isDeleted = isDeleted;
    }

    public String getValidRule() {
        return validRule;
    }

    public void setValidRule(String validRule) {
        this.validRule = validRule;
    }

    public String getOriginalName() {
        return originalName;
    }

    public void setOriginalName(String originalName) {
        this.originalName = originalName;
    }

    public Integer getSn() {
        return sn;
    }

    public void setSn(Integer sn) {
        this.sn = sn;
    }

    public Short getValueFrom() {
        return valueFrom;
    }

    public void setValueFrom(Short valueFrom) {
        this.valueFrom = valueFrom;
    }

    public String getScript() {
        return script;
    }

    public void setScript(String script) {
        this.script = script;
    }

    public Short getControlType() {
        return controlType;
    }

    public void setControlType(Short controlType) {
        this.controlType = controlType;
    }

    public Short getIsHidden() {
        return isHidden;
    }

    public void setIsHidden(Short isHidden) {
        this.isHidden = isHidden;
    }

    public Short getIsFlowVar() {
        return isFlowVar;
    }

    public void setIsFlowVar(Short isFlowVar) {
        this.isFlowVar = isFlowVar;
    }

    public String getIdentity() {
        return identity;
    }

    public void setIdentity(String identity) {
        this.identity = identity;
    }

    public String getOptions() {
        return options;
    }

    public void setOptions(String options) {
        this.options = options;
    }

    public String getCtlProperty() {
        return ctlProperty;
    }

    public void setCtlProperty(String ctlProperty) {
        this.ctlProperty = ctlProperty;
    }

    public boolean isAdded() {
        return isAdded;
    }

    public void setAdded(boolean added) {
        isAdded = added;
    }

    public Short getIsAllowMobile() {
        return isAllowMobile;
    }

    public void setIsAllowMobile(Short isAllowMobile) {
        this.isAllowMobile = isAllowMobile;
    }

    public Short getIsDateString() {
        return isDateString;
    }

    public void setIsDateString(Short isDateString) {
        this.isDateString = isDateString;
    }

    public Short getIsCurrentDateStr() {
        return isCurrentDateStr;
    }

    public void setIsCurrentDateStr(Short isCurrentDateStr) {
        this.isCurrentDateStr = isCurrentDateStr;
    }

    public String getStyle() {
        return style;
    }

    public void setStyle(String style) {
        this.style = style;
    }

    public Short getIsReference() {
        return isReference;
    }

    public void setIsReference(Short isReference) {
        this.isReference = isReference;
    }

    public String getDatefmt() {
        datefmt = StringPool.DATE_FORMAT_DATE;
        if (StringUtils.isNotEmpty(ctlProperty)) {
            try {
                JSONObject json = JSONObject.fromObject(ctlProperty);
                if(json.containsKey("format")){
                    String format = json.get("format").toString();
                    if (BeanUtils.isNotEmpty(format)) {
                        datefmt = format;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return datefmt;
    }

    public void setDatefmt(String datefmt) {
        this.datefmt = datefmt;
    }

    public String getCheckboxDefault() {
        return checkboxDefault;
    }

    public void setCheckboxDefault(String checkboxDefault) {
        this.checkboxDefault = checkboxDefault;
    }

    public String getRadioDefault() {
        return radioDefault;
    }

    public void setRadioDefault(String radioDefault) {
        this.radioDefault = radioDefault;
    }

    public String getScriptID() {
        return scriptID;
    }

    public void setScriptID(String scriptID) {
        this.scriptID = scriptID;
    }

    public short getType() {
        return type;
    }

    public void setType(short type) {
        this.type = type;
    }

    public Short getIsWebSign() {
        return isWebSign;
    }

    public void setIsWebSign(Short isWebSign) {
        this.isWebSign = isWebSign;
    }

    public Short getIsShowComdify() {
        return isShowComdify;
    }

    public void setIsShowComdify(Short isShowComdify) {
        this.isShowComdify = isShowComdify;
    }

    public String getCoinValue() {
        return coinValue;
    }

    public void setCoinValue(String coinValue) {
        this.coinValue = coinValue;
    }

    public String getFileTypes() {
        return fileTypes;
    }

    public void setFileTypes(String fileTypes) {
        this.fileTypes = fileTypes;
    }

    public static Integer getISENCRYPT() {
        return ISENCRYPT;
    }

    public static Integer getIsencryptNot() {
        return ISENCRYPT_NOT;
    }

    public Integer getIsEncrypt() {
        return isEncrypt;
    }

    public void setIsEncrypt(Integer isEncrypt) {
        this.isEncrypt = isEncrypt;
    }

    public String getEncryptClass() {
        return encryptClass;
    }

    public void setEncryptClass(String encryptClass) {
        this.encryptClass = encryptClass;
    }

    public String getDecryptClass() {
        return decryptClass;
    }

    public void setDecryptClass(String decryptClass) {
        this.decryptClass = decryptClass;
    }

    public String getDictName() {
        return dictName;
    }

    public void setDictName(String dictName) {
        this.dictName = dictName;
    }

    public int getListShow() {
        return listShow;
    }

    public void setListShow(int listShow) {
        this.listShow = listShow;
    }

    public int getDialogShow() {
        return dialogShow;
    }

    public void setDialogShow(int dialogShow) {
        this.dialogShow = dialogShow;
    }

    @Override
    public String toString() {
        return "FormField{" +
                "fieldId='" + fieldId + '\'' +
                ", tableId='" + tableId + '\'' +
                ", fieldName='" + fieldName + '\'' +
                ", fieldType='" + fieldType + '\'' +
                ", isRequired=" + isRequired +
                ", isList=" + isList +
                ", isQuery=" + isQuery +
                ", fieldDesc='" + fieldDesc + '\'' +
                ", charLen=" + charLen +
                ", intLen=" + intLen +
                ", decimalLen=" + decimalLen +
                ", dictType='" + dictType + '\'' +
                ", isDeleted=" + isDeleted +
                ", validRule='" + validRule + '\'' +
                ", originalName='" + originalName + '\'' +
                ", sn=" + sn +
                ", valueFrom=" + valueFrom +
                ", script='" + script + '\'' +
                ", controlType=" + controlType +
                ", isHidden=" + isHidden +
                ", isFlowVar=" + isFlowVar +
                ", identity='" + identity + '\'' +
                ", options='" + options + '\'' +
                ", ctlProperty='" + ctlProperty + '\'' +
                ", isAdded=" + isAdded +
                ", isAllowMobile=" + isAllowMobile +
                ", isDateString=" + isDateString +
                ", isCurrentDateStr=" + isCurrentDateStr +
                ", style='" + style + '\'' +
                ", isReference=" + isReference +
                ", datefmt='" + datefmt + '\'' +
                ", checkboxDefault='" + checkboxDefault + '\'' +
                ", radioDefault='" + radioDefault + '\'' +
                ", scriptID='" + scriptID + '\'' +
                ", type=" + type +
                ", isWebSign=" + isWebSign +
                ", isShowComdify=" + isShowComdify +
                ", coinValue='" + coinValue + '\'' +
                ", fileTypes='" + fileTypes + '\'' +
                ", isEncrypt=" + isEncrypt +
                ", encryptClass='" + encryptClass + '\'' +
                ", decryptClass='" + decryptClass + '\'' +
                ", dictName='" + dictName + '\'' +
                '}';
    }

    /**
     * 获取json对象
     *
     * @return 字符串
     */
    public String getJsonOptions() {
        if (StringUtil.isEmpty(this.options)) {
            return "";
        }
        if (StringUtil.isJson(this.options)) {
            return this.options.replaceAll("\"", "'");
        }

        JSONArray array = new JSONArray();
        if (!StringUtil.isJson(this.options)) {
            String[] ary = this.options.split("\n");
            for (String opt : ary) {
                array.add(new JSONObject().accumulate("key", opt).accumulate(
                        "value", opt));
            }
        }
        String reStr = array.toString();
        reStr = reStr.replaceAll("\"", "'");
        return reStr;
    }

    /**
     * 选项构建成hashmap对象。
     *
     * @return
     */
    public Map<String, Object> getAryOptions() {
        Map<String, Object> map = new LinkedHashMap<>();
        if (StringUtil.isEmpty(this.options) || "null".equals(this.options)) {
            return map;
        }
        if (StringUtil.isJson(this.options)) {
            JSONArray jArray = JSONArray.fromObject(this.options);
            for (Object obj : jArray) {
                JSONObject jObject = (JSONObject) obj;
                String key = jObject.getString("key");
                String value = jObject.getString("value");
                map.put(key, value);
            }
        } else {
            String[] ary = this.options.split("\n");
            for (String opt : ary) {
                map.put(opt, opt);
            }
        }
        return map;
    }

    /**
     * 将控件属性转换成map输出。
     *
     * @return map
     */
    public Map<String, String> getPropertyMap() {
        Map<String, String> map = new HashMap<>(16);
        if (StringUtil.isEmpty(this.ctlProperty)) {
            return map;
        }
        try {
            JSONObject jsonObject = JSONObject.fromObject(this.ctlProperty);
            if (jsonObject.size() > 0) {
                Iterator it = jsonObject.keys();
                while (it.hasNext()) {
                    String key = it.next().toString();
                    String value = jsonObject.getString(key);
                    map.put(key, value);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return map;
    }

    /**
     * 是否选择器的隐藏字段
     *
     * @return
     */
    public boolean isExecutorSelectorHidden() {
        if (BeanUtils.isEmpty(controlType)) {
            return false;
        }
        if (controlType == FieldPool.SELECTOR_USER_SINGLE
                || controlType == FieldPool.SELECTOR_USER_MULTI
                || controlType == FieldPool.SELECTOR_ORG_SINGLE
                || controlType == FieldPool.SELECTOR_ORG_MULTI
                || controlType == FieldPool.SELECTOR_ROLE_SINGLE
                || controlType == FieldPool.SELECTOR_ROLE_MULTI
                || controlType == FieldPool.SELECTOR_POSITION_SINGLE
                || controlType == FieldPool.SELECTOR_POSITION_MULTI) {
            if (isHidden == FormField.HIDDEN) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }
}